<?php

namespace RedMVC;

/**
 * Acl class
 *
 * @category    RedMVC
 * @author      Jan Fischer, bitWorking <info@bitworking.de>
 */
class Acl{

    const ROLE_ALL = 'aclRoleAll';

    protected $_acl = array();

    /**
     * sets privileges/recources for given role
     *
     * @param string|null $role
     * @param string|null $resource
     * @param string|array|null $privileges
     */
    public function allow($role = null, $resource = null, $privileges = null){
        if(null === $role){
            $role = self::ROLE_ALL;
        }
        if(null === $resource){
            $this->_acl[(string) $role] = true;
        }
        else if(null === $privileges){
            $this->_acl[(string) $role][(string) $resource] = true;
        }
        else{
            if(is_array($privileges)){
                foreach($privileges as $privilege){
                    $this->_acl[(string) $role][(string) $resource][(string) $privilege] = true;
                }
            }
            else{
                $this->_acl[(string) $role][(string) $resource][(string) $privileges] = true;
            }
        }
    }

    /**
     * proofs if privilege/resource is allowed for role
     *
     * @param string $role
     * @param string $resource
     * @param string $privilege
     * @return bool
     */
    public function isAllowed($role, $resource, $privilege){
        if(isset($this->_acl[self::ROLE_ALL])
           && true === $this->_acl[self::ROLE_ALL]){
            return true;
        }
        if(isset($this->_acl[self::ROLE_ALL][(string) $resource])
           && true === $this->_acl[self::ROLE_ALL][(string) $resource]){
            return true;
        }
        if(isset($this->_acl[self::ROLE_ALL][(string) $resource][(string) $privilege])
           && true === $this->_acl[self::ROLE_ALL][(string) $resource][(string) $privilege]){
            return true;
        }
        if(!isset($this->_acl[(string) $role])){
            return false;
        }
        if(true === $this->_acl[(string) $role]){
            return true;
        }
        if(!isset($this->_acl[(string) $role][(string) $resource])){
            return false;
        }
        if(true === $this->_acl[(string) $role][(string) $resource]){
            return true;
        }
        if(isset($this->_acl[(string) $role][(string) $resource][(string) $privilege])){
            return true;
        }
        return false;
    }

    /**
     * magic __toString method
     *
     * @return string
     */
    public function __toString(){
        $out = '<pre>';
        $out .= print_r($this->_acl, true);
        $out .= '</pre>';
        return $out;
    }
}